package com.lab.account.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.common.service.ExistenceException;
import com.common.service.NoSuchUserException;
import com.common.service.ServiceException;
import com.common.util.EntityUtils;
import com.common.web.Json;
import com.common.web.JsonResponse;
import com.lab.account.domain.Role;
import com.lab.account.domain.User;
import com.lab.account.domain.UserVo;
import com.lab.account.service.UserManager;

@Controller
@RequestMapping("/account/*")
public class UserController {

    @Autowired
    private UserManager userManager;

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public String list(HttpServletRequest request, HttpServletResponse response) {
        try {
            WebAuthenticationDetails authDetail = (WebAuthenticationDetails) SecurityContextHolder
                    .getContext().getAuthentication().getDetails();

            List<User> list = userManager.getAll();
            request.getSession().setAttribute("userList", list);
        } catch (ServiceException e) {
            e.printStackTrace();
        }

        return "account/user-list";
    }

    @RequestMapping(value = "/users/{userId}", method = RequestMethod.GET)
    public String display(HttpServletRequest request,
            HttpServletResponse response, @PathVariable
            Long userId) {
        HttpSession session = request.getSession();
        try {
            if (userId == -1) {
                Collection<Role> roleList = userManager.getRoleList();
                session.setAttribute("availiableRoleList", roleList);
                session.removeAttribute("user");
                session.removeAttribute("grantedRoleList");

            } else {
                User user = userManager.get(userId);
                Collection<Role> roleList = userManager.getRoleList();
                Collection<Role> grantedRoleList = user.getRoleList();
                Collection<Role> availiableRoleList = CollectionUtils.subtract(
                        roleList, grantedRoleList);
                session.setAttribute("user", user);
                session.setAttribute("availiableRoleList", availiableRoleList);
                session.setAttribute("grantedRoleList", grantedRoleList);
            }
        } catch (ServiceException e) {
            e.printStackTrace();
        }

        return "account/user-display";
    }

    @RequestMapping(value = "/users/{userId}", method = RequestMethod.DELETE)
    public String delete(HttpServletRequest request,
            HttpServletResponse response, @PathVariable
            Long userId) {
        try {
            userManager.remove(userId);
        } catch (ServiceException e) {
            e.printStackTrace();
        }

        // response.sendRedirect(request.getContextPath() + "/account/user");
        // request.getRequestDispatcher(request.getContextPath() + "/account/user").forward(request, response);

        return "redirect:/account/users"; // return "redirect:/account/user.do"; 
    }

    @RequestMapping(value = "/users", method = RequestMethod.POST)
    public String save(HttpServletRequest request,
            HttpServletResponse response, User user, String flag,
            String... role) {

        List<Role> roleList = new ArrayList<Role>();
        if (role != null) {
            for (String ro : role) {
                Role entity = new Role();
                entity.setId(Long.parseLong(ro));

                roleList.add(entity);
            }
        }

        user.setRoleList(roleList);

        try {
            userManager.save(user);
        } catch (ServiceException e) {
            e.printStackTrace();
        }

        return "redirect:/account/users";
    }

    @RequestMapping(value = "/user/checkUsername", method = RequestMethod.GET)
    @ResponseBody
    public Json checkUsername(HttpServletRequest request,
            HttpServletResponse response, String username, String oldUsername)
            throws ServiceException {
        boolean isUnique = userManager.isUsernameUnique(username, oldUsername);
        if (isUnique) {
            return JsonResponse.write(true, "username is availiable.");
        }

        throw new ExistenceException();
    }

    @RequestMapping(value = "/user/login", method = RequestMethod.POST)
    public @ResponseBody
    Object login(User user) {
        try {
            User dbUser = userManager.login(user);

            return EntityUtils.merge(new UserVo(), dbUser);
        } catch (NoSuchUserException e) {
            return new UserVo();
        }
    }
}
